﻿// Solution: TESZT
// Project: WpfApplication2
// FileName: ScriptReader.cs
// Created: 2015.07.14 17:03
// Last format: 2015.07.14 17:03
// UserName: kp

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace System.Common.IO
{
  public class ScriptReader : IDisposable
  {
    private const int EOF = -1;
    private const char CR = '\r';
    private const char LF = '\n';

    private readonly BinaryReader fReader;

    protected ScriptReader( string content, Encoding encoding )
    {
      fReader = new BinaryReader( new MemoryStream( encoding.GetBytes( content ) ), encoding );
    }

    public static ScriptReader CreateFromFile( string fileName )
    {
      var encoding = Encoding.GetEncoding( 1250 );
      var content = File.ReadAllText( fileName, encoding );
      return new ScriptReader( content, encoding );
    }

    public static ScriptReader CreateFromString( string content )
    {
      var encoding = Encoding.GetEncoding( 1250 );
      return new ScriptReader( content, encoding );
    }

    public bool NextChar()
    {
      if ( Eof )
        return false;

      Prev = Current;
      Current = fReader.Read();
      Next = fReader.PeekChar();

      Eof = Current == EOF;

      return !Eof;
    }

    public void ReadAtEol()
    {
      var ref_line = string.Empty;
      ReadAtEol( ref ref_line );
    }

    public void ReadAtEol( ref string line )
    {
      var sb = new StringBuilder();

      while ( NextChar() )
      {
        if ( Current == CR )
        {
          if ( Next == LF )
            NextChar();

          break;
        }

        sb.Append( (char) Current );
      }

      line = sb.ToString();
    }

    public bool ReadAtSeparator( char separator )
    {
      var ref_line = string.Empty;
      return ReadAtSeparator( separator, ref ref_line );
    }

    public bool ReadAtSeparator( char separator, ref string line )
    {
      line = string.Empty;
      var sb = new StringBuilder();

      while ( NextChar() )
      {
        sb.Append( (char) Current );
        if ( Current != separator )
          continue;

        break;
      }

      if ( Current != separator )
        return false;

      NextChar();

      line = sb.ToString();
      return true;
    }

    public bool ReadAtSeparator( string separator )
    {
      var ref_line = string.Empty;
      return ReadAtSeparator( separator, ref ref_line );
    }

    public bool ReadAtSeparator( string separator, ref string line )
    {
      line = string.Empty;

      var sb = new StringBuilder();

      while ( NextChar() )
      {
        sb.Append( (char) Current );
        if ( !sb.ToString().EndsWith( separator ) )
          continue;

        break;
      }

      if ( !sb.ToString().EndsWith( separator ) )
        return false;
      
      NextChar();
      line = sb.ToString();
      return true;
    }

    public bool Eof { get; private set; }

    public int Prev { get; private set; }
    public int Next { get; private set; }
    public int Current { get; private set; }

    public int Position { get { return (int) fReader.BaseStream.Position; } }

    public long Seek( long offset, SeekOrigin origin )
    {
      return fReader.BaseStream.Seek( offset, origin );
    }

    public int Read( char[] buffer, int index, int count )
    {
      return fReader.Read( buffer, index, count );
    }

    public void Dispose()
    {
      fReader.Dispose();
    }

  }
}